package fr.istic.mmm.coursepoursuite;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

import fr.istic.mmm.coursepoursuite.app.App;
import fr.istic.mmm.coursepoursuite.parcours.Parcours;
import fr.istic.mmm.coursepoursuite.parcours.Point;
import fr.istic.mmm.coursepoursuite.simulateur.Simulateur;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.SystemClock;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.TextView;

@SuppressLint("SetJavaScriptEnabled")
public class RunningActivity extends Activity {

	WebView webViewMap;
	Chronometer chronometer;
	Button changeStatus;
	boolean status;
	Long pauseTime;
	Timer timer = null;
	Simulateur simulateur;
	Point dernierPoint = null;
	double distanceTotale = 0;
	double rythme = 0;
	double temps = 0;
	Parcours parcours = null;
	Parcours ghostParcours = null;
	double kmEnCours = 0.1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_running);
		
		// affichage de la map
		webViewMap = (WebView)findViewById(R.id.webViewMap);
		webViewMap.loadUrl("file:///android_asset/googleMap/map.html");
		webViewMap.getSettings().setJavaScriptEnabled(true);
		webViewMap.getSettings().setAllowFileAccess(true);

		// Charge le mode ghost
		this.ghostParcours = this.ghostParcours();
		if(this.ghostParcours == null)
			System.out.println("Mode Normal");
		else
		{
			System.out.println("Mode Ghost");
			webViewMap.setWebViewClient(new WebViewClient()
			{
				@Override
				// Attendre que la map soit charg�e
			    public void onPageFinished(WebView view, String url)
				{
					super.onPageFinished(view, url);
					try
					{
					    Thread.sleep(2000);
					    webViewMap.loadUrl("javascript:stringJson('" + ghostParcours.createJSONPoints() + "')");
					}
					catch(InterruptedException ex)
					{
					    Thread.currentThread().interrupt();
					}
			    }
			});
		}
		// bouton Start Stop
		changeStatus = (Button)findViewById(R.id.boutonRejouer);
		changeStatus.setBackgroundResource(R.drawable.pause);
		
		// Initialisation du simulateur
		simulateur = new Simulateur(this);
		
		// Initialisation du chronom�tre
		startChronometer();
		
		// bouton stop
		final Button btnStop = (Button) findViewById(R.id.btnStop);
		btnStop.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				terminerParcours(); // arrêt du parcours et enregistrement
			}
		});
	}
	
	/**
	 * Initialise le mode Ghost
	 */
	private Parcours ghostParcours()
	{
		Parcours ghostParcours = null;
		
		try
		{
	        Bundle extra = getIntent().getExtras();
			String idGhostParcours = extra.getString("ghostParcours");

			final App application = (App)getApplicationContext();
			ghostParcours = application.getParcours(idGhostParcours);
		}
		catch (Exception e) { }
		
		return ghostParcours;
	}
	
	/**
	 * D�marre le chronom�tre
	 */
	public void startChronometer()
	{
		((Chronometer) findViewById(R.id.chronometer1)).start();
		((Chronometer) findViewById(R.id.chronometer1)).setBase(SystemClock.elapsedRealtime());
		status = true;
		initParcours();
		lancerSimulateur();
	}
	
	/**
	 * M�thode appel�e lors de la pause/relance du chrono
	 * @param view
	 */
	public void changeStatusChronometer(View view)
	{
		if(status)
		{
			((Button) findViewById(R.id.boutonRejouer)).setBackgroundResource(R.drawable.play);
			status = false;
			((Chronometer) findViewById(R.id.chronometer1)).stop();
			pauseTime = SystemClock.elapsedRealtime() - Long.valueOf(((Chronometer) findViewById(R.id.chronometer1)).getBase());
			pauseSimulateur();
		}
		else
		{
			((Chronometer) findViewById(R.id.chronometer1)).setBase(SystemClock.elapsedRealtime() - pauseTime);
			((Chronometer) findViewById(R.id.chronometer1)).start();
			((Button) findViewById(R.id.boutonRejouer)).setBackgroundResource(R.drawable.pause);
			status = true;
			lancerSimulateur();
		}
	}
	
	/**
	 * Méthode qui démarre le simulateur
	 */
	public void lancerSimulateur(){
		timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						// affichage des points
						Point point = simulateur.getNextPoint();
						if(point != null){
							temps = Double.parseDouble(String.valueOf(SystemClock.elapsedRealtime() - ((Chronometer) findViewById(R.id.chronometer1)).getBase()));
							point.setTemps(temps);
							
							parcours.addPoint(point);
							
							// affichage de la distance
							TextView textViewDist = (TextView)findViewById(R.id.textView5);
							textViewDist.setText(calculDistance(point));
							
							// affichage du rythme
							TextView textViewRythme = (TextView)findViewById(R.id.textView6);
							textViewRythme.setText(calculRythme());
							
							// affichage du point sur la map
							webViewMap.loadUrl("javascript:addToPoly(" + point.getLat() + ", " + point.getLng() + ")");
						}
						else
						{
							// trajet terminé
							terminerParcours();
						}
					}
				});
			}
		}, 0, 2000);
	}
	
	/**
	 * Méthode qui initialise un parcours
	 */
	@SuppressLint("SimpleDateFormat")
	public void initParcours(){
		parcours = new Parcours();
		final App application = (App)getApplicationContext();
		application.addParcours(parcours);
		DateFormat dateFormat = new SimpleDateFormat("dd-mm-yyyy HH:mm:ss");
		Calendar cal = Calendar.getInstance();
		parcours.setDate(dateFormat.format(cal.getTime()));
	}
	
	/**
	 * Méthode qui enregistre les données dans le parcours
	 */
	public void terminerParcours(){
		((Chronometer) findViewById(R.id.chronometer1)).stop();
		pauseSimulateur();
		
		temps = Double.parseDouble(String.valueOf(SystemClock.elapsedRealtime() - ((Chronometer) findViewById(R.id.chronometer1)).getBase()));
		parcours.setDistanceTotale(distanceTotale);
		parcours.setTemps(temps);
		parcours.setRythme(rythme);
		
		// naviguer vers la page FinRunningActivity
		((App)getApplicationContext()).addParcours(parcours);
		Intent finRunningIntent = new Intent(getApplicationContext(), FinRunningActivity.class);
		finRunningIntent.putExtra("parcours", parcours.getDate());
		
		if(ghostParcours != null)
			finRunningIntent.putExtra("ghostParcours", ghostParcours.getDate());
		
		startActivity(finRunningIntent);
		finish();
	}
	
	/**
	 * Méthode qui met en pause le simulateur
	 */
	public void pauseSimulateur(){
		if(timer != null){
			timer.cancel();
		}
	}
	
	/**
	 * Méthode qui calcul la distance entre deux points GPS
	 * @param a
	 * @param b
	 * @return
	 */
	public String calculDistance(Point b) {
		
		if(dernierPoint != null){
			double lat1 = Math.toRadians(dernierPoint.getLat());
			double lon1 = Math.toRadians(dernierPoint.getLng());
			double lat2 = Math.toRadians(b.getLat());
			double lon2 = Math.toRadians(b.getLng());
			
	        // d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
			
			double km = Math.acos(
		            Math.sin(lat1)*Math.sin(lat2)+Math.cos(lat1)*Math.cos(lat2)*Math.cos(lon1-lon2)
			        );
			distanceTotale += km*6366;
		}
		dernierPoint = b;
		
		//vérifie si on a dépasser un nouveau km (ici tous les 100m pour la démo)
		if(distanceTotale > kmEnCours){
			jouerSon();
			kmEnCours += 0.1;
		}
		
		DecimalFormat df = new DecimalFormat("#0.00");
		return df.format(distanceTotale) + " km";
    }
	
	/**
	 * Méthode qui calcul le rythme en min/km
	 */
	public String calculRythme(){
		
		if(distanceTotale != 0){
			long elapsedMillis = SystemClock.elapsedRealtime() - ((Chronometer) findViewById(R.id.chronometer1)).getBase();
		    double tps = ((Double.parseDouble(String.valueOf(elapsedMillis))/60000));
		    rythme = tps / distanceTotale;
		    int min = (int) rythme;
		    int sec = (int) ((rythme - min) * 60);
		    
		    return min + "min " + sec  + "sec/km";
		}
		return "0.00 min/km";
	}
	
	/**
	 * Méthode qui joue un son à chaque km parcouru
	 */
	public void jouerSon(){
		// play sound
		AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		//int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		int volume = 2;
		am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);

		MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.bip);
		mediaPlayer.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.action_accueil:
			Intent accueilIntent = new Intent(getApplicationContext(), MainActivity.class);
			startActivity(accueilIntent);
			finish();
			return true;
		case R.id.action_options:
			Intent optionsIntent = new Intent(getApplicationContext(), OptionsActivity.class);
			startActivity(optionsIntent);
			finish();
			return true;
		case R.id.action_historique:
			Intent historiqueIntent = new Intent(getApplicationContext(), HistoriqueActivity.class);
			startActivity(historiqueIntent);
			finish();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
}
